﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Marbles.Core.Web.Resources;

namespace Marbles.Core.Web.Controls
{
    [ToolboxData("<{0}:UpdateRegion runat=server></{0}:UpdateRegion>")]
    public class UpdateRegion : Panel, ICallbackEventHandler
    {

        [Category("Actions")]
        public event EventHandler Updating;
        [Category("Actions")]
        public event EventHandler Updated;

        [Category("Behaviour")]
        public bool AsynchronousCallback
        {
            get
            {
                object obj = ViewState["AsynchronousCallback"];
                if (obj == null) { return true; }
                return Convert.ToBoolean(obj);
            }
            set { ViewState["AsynchronousCallback"] = value; }
        }

        [Category("Behaviour")]
        public int AutoRefreshInterval
        {
            get
            {
                object obj = ViewState["AutoRefreshInterval"];
                if (obj == null) { return 60000; }
                return Convert.ToInt32(obj);
            }
            set { ViewState["AutoRefreshInterval"] = value; }
        }


        [Category("Behaviour")]
        public bool AutoRefresh
        {
            get
            {
                object obj = ViewState["AutoRefresh"];
                if (obj == null) { return false; }
                return Convert.ToBoolean(obj);
            }
            set { ViewState["AutoRefresh"] = value; }
        }

        [Category("Appearance")]
        public string InnerHTML
        {
            get
            {
                return this._innerHtml;
            }
            set
            {
                this._innerHtml = value;
            }
        }

        [Category("Behaviour")]
        public string CallbackControlId
        {
            get
            {
                object obj = ViewState["CallbackControlId"];
                if (obj == null) { return string.Empty; }
                return (string)obj;
            }
            set { ViewState["CallbackControlId"] = value; }
        }

        private string _innerHtml = string.Empty;

        protected override void OnLoad(EventArgs e)
        {
            if (!Page.ClientScript.IsClientScriptBlockRegistered("UpdateRegion"))
            {
                Page.ClientScript.RegisterClientScriptBlock(typeof(System.String), "UpdateRegion", GetScript(), true);
            }

            base.OnLoad(e);

            if (CallbackControlId != string.Empty)
            {
                Control ctl = Page.FindControl(CallbackControlId);
                if (ctl != null)
                {
                    if (ctl.GetType() == typeof(Button))
                    {
                        Button btn = ctl as Button;
                        btn.OnClientClick = GetCallbackScript();
                    }

                    if (ctl.GetType() == typeof(HtmlButton))
                    {
                        HtmlButton btn = ctl as HtmlButton;
                        btn.Attributes.Add("onclick", GetCallbackScript());
                    }

                }
            }

            if (this.AutoRefresh)
            {
                if (!Page.ClientScript.IsClientScriptBlockRegistered(this.ClientID))
                {
                    Page.ClientScript.RegisterClientScriptBlock(typeof(System.String), this.ClientID, GetTimerScript(), true);
                }
            }
        }

        private string GetCallbackScript()
        {
            return Page.ClientScript.GetCallbackEventReference(this, string.Format("document.getElementById('{0}').innerHTML", this.ClientID), "UpdateRegion_Return", this.ClientID, "UpdateRegion_Error", this.AsynchronousCallback) + ";return false;";
        }

        public string GetCallbackResult()
        {
            if (this.Updated != null) { Updated(this, EventArgs.Empty); }
            return this._innerHtml;
        }

        public void RaiseCallbackEvent(string eventArgument)
        {
            this._innerHtml = eventArgument;
            if (this.Updating != null) { Updating(this, EventArgs.Empty); }
        }

        private string GetTimerScript()
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine(string.Format("function {0}_Tick()", this.ClientID));
            sb.AppendLine("{");
            sb.AppendLine(GetCallbackScript());
            sb.AppendLine("}");

            sb.AppendLine(string.Format("var {0}_timer = self.setInterval('{0}_Tick()', {1});", this.ClientID, this.AutoRefreshInterval));
            return sb.ToString();
        }

        private string GetScript()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("function UpdateRegion_InitialiseTimer(interval, context) {");
            sb.AppendLine("}");
            sb.AppendLine("function UpdateRegion_Tick() {");
            sb.AppendLine("}");
            sb.AppendLine("function UpdateRegion_Return(arg, context) {");
            sb.AppendLine("context.innerHTML = arg;");
            sb.AppendLine("}");
            sb.AppendLine("function UpdateRegion_Error(arg, context) {");
            sb.AppendLine("alert('An error occured in processing of ' + context.id + '\\n' + arg);");
            sb.AppendLine("}");
            return sb.ToString();
        }

    }
}
